import 'package:flutter_scaffold_plugin/base/base.dart';
import 'package:flutter_scaffold_plugin/base/base_page.dart';
import 'package:flutter_scaffold_plugin/components/gesture_avoid_detector.dart';
import 'package:flutter_scaffold_plugin/components/navigation_bar.dart';
import 'package:flutter_scaffold_plugin/pages/teacher/teacher_living_page.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart' as WebRTC;

class StudentsController extends TemplateController {
  final _remoteRenderer = RTCVideoRenderer();
  WebRTC.MediaStream _localStream;
  RTCPeerConnection _peerConnection;
  List<WebRTC.MediaDeviceInfo> mediaDevicesList;

  String get sdpSemantics => 'unified-plan';

  RTCVideoRenderer remoteRenderer;

  final _hasIntilized = false.obs;
  get hasIntilized => this._hasIntilized.value;
  set hasIntilized(value) => this._hasIntilized.value = value;

  @override
  void onInit() {
    super.onInit();
    _initRenderers();
  }

  void _initRenderers() async {
    await _remoteRenderer.initialize();
    // await _makeCall();
  }

  // Platform messages are asynchronous, so we initialize in an async method.
  _makeCall() async {
    var configuration = <String, dynamic>{
      'iceServers': [
        {
          'url': 'stun:stun.l.google.com:19302',
        },
      ],
      'sdpSemantics': sdpSemantics
    };

    final offerSdpConstraints = <String, dynamic>{
      'mandatory': {
        'OfferToReceiveAudio': true,
        'OfferToReceiveVideo': true,
      },
      'optional': [],
    };

    final mediaConstraints = <String, dynamic>{
      'audio': true,
      'video': {
        'mandatory': {
          'minWidth':
              '1280', // Provide your own width, height and frame rate here
          'minHeight': '720',
          'minFrameRate': '30',
        },
        'facingMode': 'user',
        'optional': [],
      }
    };
    if (_peerConnection != null) return;

    try {
      _peerConnection =
          await createPeerConnection(configuration, offerSdpConstraints);
      _peerConnection.onSignalingState = _onSignalingState;
      _peerConnection.onIceGatheringState = _onIceGatheringState;
      _peerConnection.onIceConnectionState = _onIceConnectionState;
      _peerConnection.onConnectionState = _onPeerConnectionState;
      _peerConnection.onIceCandidate = _onCandidate;
      _peerConnection.onRenegotiationNeeded = _onRenegotiationNeeded;

      _peerConnection.onTrack = _onTrack;
      _peerConnection.onAddTrack = _onAddTrack;
      _peerConnection.onRemoveTrack = _onRemoveTrack;

      // _localStream =
      //     await WebRTC.navigator.mediaDevices.getUserMedia(mediaConstraints);
      mediaDevicesList = await WebRTC.navigator.mediaDevices.enumerateDevices();
      _localStream.getTracks().forEach((track) {
        _peerConnection.addTrack(track, _localStream);
      });
      // _remoteRenderer.srcObject = _localStream;

      //change for loopback.
      var description = await _peerConnection.createOffer(offerSdpConstraints);
      var sdp = description.sdp;
      print('sdp = $sdp');
      await _peerConnection.setLocalDescription(description);
      description.type = 'answer';
      await _peerConnection.setRemoteDescription(description);
    } catch (e) {
      print(e.toString());
    }
    hasIntilized = true;
  }

  void _onSignalingState(RTCSignalingState state) {
    print(state);
  }

  void _onIceGatheringState(RTCIceGatheringState state) {
    print(state);
  }

  void _onIceConnectionState(RTCIceConnectionState state) {
    print(state);
  }

  void _onPeerConnectionState(RTCPeerConnectionState state) {
    print(state);
  }

  void _onCandidate(RTCIceCandidate candidate) {
    print('onCandidate: ${candidate.candidate}');
    _peerConnection.addCandidate(candidate);
  }

  void _onTrack(RTCTrackEvent event) {
    print('onTrack');
    if (event.track.kind == 'video') {
      _remoteRenderer.srcObject = event.streams[0];
    }
  }

  void _onAddTrack(MediaStream stream, MediaStreamTrack track) {
    if (track.kind == 'video') {
      _remoteRenderer.srcObject = stream;
    }
  }

  void _onRemoveTrack(MediaStream stream, MediaStreamTrack track) {
    if (track.kind == 'video') {
      _remoteRenderer.srcObject = null;
    }
  }

  void _onRenegotiationNeeded() {
    print('RenegotiationNeeded');
  }

  void _hangUp() async {
    try {
      await _peerConnection.close();
      _peerConnection = null;
      _remoteRenderer.srcObject = null;
    } catch (e) {
      print(e.toString());
    }
  }

  @override
  void onClose() {
    super.onClose();
    if (initialized) {
      _hangUp();
    }
    _remoteRenderer.dispose();
  }
}

class StudentPage extends TemplatePage<StudentsController> {
  @override
  Widget buildBody(BuildContext context) {
    return Stack(
      children: [
        Obx(
          () => Container(
            child: !this.controller.hasIntilized
                ? Container()
                : Container(
                    margin: EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 0.0),
                    width: Get.width,
                    height: Get.height,
                    decoration: BoxDecoration(color: Colors.black),
                    child: RTCVideoView(this.controller.remoteRenderer),
                  ),
          ),
        ),
        Align(
          alignment: Alignment.topCenter,
          child: GestureAvoidDetector(
            onTap: () {},
            child: Container(
              child: NavigationBar.customBar(
                  title: "学生",
                  foregroundColor: Colors.white,
                  backgroundColor: Color.fromARGB(80, 0, 0, 0)),
            ),
          ),
        ),
      ],
    );
  }

  @override
  StudentsController initController() {
    return StudentsController();
  }

  @override
  Widget buildNavigationBar(BuildContext context) {
    return null;
  }
}
